package util;

import com.alibaba.fastjson.JSON;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.ReadContext;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.wltea.expression.ExpressionEvaluator;
import org.wltea.expression.IllegalExpressionException;
import org.wltea.expression.datameta.Variable;

import java.util.ArrayList;
import java.util.List;

/**
 * \* User: MeiZhongHao
 * \* Date: 2019-01-24
 * \* Time: 15:11
 * \* Description: IK表达式计算引擎，结合JSONPath表达式，支持简单计算
 * \
 */
public class IKUtil {

    public static final Logger LOGGER = LoggerFactory.getLogger(IKUtil.class);

    public static final String JSON_PATH_SPLIT = ";";

    public static final String KEY_VALUE_SPLIT = "=";

    /***
     * JSONPath 结合 IK表达式 支持简单计算
     * @param rule
     * @param jsonPaths
     * @param data
     * @return
     */
    public static <T> T evaluate(String rule, String jsonPaths, String data) throws IllegalExpressionException {
        if (StringUtils.isEmpty(rule)) {
            LOGGER.warn("IK表达式为空");
            throw new IllegalExpressionException("IK表达式为空");
        }
        // 解析jsonPath
        String[] variablesPaths = StringUtils.split(jsonPaths, JSON_PATH_SPLIT);
        List<Variable> variables = new ArrayList<>();

        if (!StringUtils.isEmpty(jsonPaths) && !StringUtils.isEmpty(data)) {
            ReadContext ctx = JsonPath.parse(data);
            for (String path : variablesPaths) {
                // 解析Key_Value
                int varIdx = path.indexOf(KEY_VALUE_SPLIT, 0);
                String varName = path.substring(0, varIdx);
                //json-path表达式
                String varJsonPath = path.substring(varIdx + 1, path.length());
                if (StringUtils.isAnyEmpty(varName, varJsonPath)) {
                    LOGGER.warn("JSONPath表达式出错", varJsonPath);
                    break;
                }
                try {
                    variables.add(Variable.createVariable(varName, ctx.read(varJsonPath)));
                } catch (Exception e) {
                    LOGGER.warn("JSONPath表达式解析出错", varJsonPath, data);
                }
            }
        }
        // 执行IK表达式引擎
        try {
            return (T) ExpressionEvaluator.evaluate(rule, variables);
        } catch (Exception e) {
            throw new IllegalExpressionException("IK表达式解析出错，rule : " + rule + "，variables : " + JSON.toJSONString(variables) + "，data : " + data);
        }
    }

}